package com.oracle.application.config;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.oracle.application.entity.Orders;
import com.oracle.application.entity.Paylog;
import com.oracle.application.entity.vo.PayAsyncVo;
import com.oracle.application.entity.vo.PayVo;
import com.oracle.application.service.IOrdersService;
import com.oracle.application.service.IPaylogService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Map;

/**
 * @author 莉丝妲黛
 */
@ConfigurationProperties(prefix = "payconfig")
@Component
@Data
@Slf4j
public class PayConfig {

    @Autowired
    private IPaylogService iPaylogService;
    @Autowired
    private IOrdersService iOrdersService;

    //#支付包沙箱AppID
    private String app_id;
    //#支付宝网关
    private String payGateway;
    //#异步回调
    private String notify_url;
    //#同步回调
    private String return_url;
    //#公钥
    private String publicKey;
    //#私钥
    private String privateKey;

    final String payStatus = "TRADE_SUCCESS";

    public String doPay(PayVo payVo, Integer orderId) {
        //根据支付宝的配置生成一个支付客户端
        AlipayClient client = new DefaultAlipayClient(payGateway, app_id, privateKey, "json", "utf-8", publicKey, "RSA2");
        //创建一个支付请求   设置请求参数
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        //异步回调
        request.setNotifyUrl(notify_url);
        //同步回调
        request.setReturnUrl(return_url);
        //支付日志
        Paylog paylog = new Paylog();
        paylog.setCreatedate(LocalDateTime.now());
        paylog.setModifydate(LocalDateTime.now());
        paylog.setOrdersn(payVo.getOut_trade_no());
        paylog.setPayprice(new BigDecimal(payVo.getTotal_amount()));
        paylog.setMember(1);
        paylog.setContent("{" + "订单编号为:" + payVo.getOut_trade_no() + "时间为:" + LocalDateTime.now() + "正在向支付宝发起支付请求,发起请求的支付金额为" + payVo.getTotal_amount() + "}");
        paylog.setOrders(orderId);
        paylog.setStatus(2);
        //持久化
        this.iPaylogService.save(paylog);
        //参数  支付日志id
        payVo.setPassback_params(paylog.getId() + "");
        request.setBizContent(JSONObject.toJSONString(payVo));
        String resultPage = null;
        try {
            resultPage = client.pageExecute(request).getBody();
            //System.out.println("resultPage = " + resultPage);
            return resultPage;
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return resultPage;
    }

    /**
     * 同步回调
     * @param payAsyncVo
     * @return
     */
    public boolean returnVerifySignTrue(PayAsyncVo payAsyncVo) {
        //订单编号
        System.out.println(payAsyncVo);
        String orderSn = payAsyncVo.getOut_trade_no();
        Orders orders =new Orders();
        orders.setOrdersn(orderSn);
        QueryWrapper<Orders> wrapper =new QueryWrapper<>(orders);
        Orders orders1=this.iOrdersService.getOne(wrapper);
        if (orders1.getOrderstatus()==1) {
            return true;
        }
        return false;
    }

    /**
     * 验证签名并处理一些核心业务
     *
     * @param payAsyncVo
     * @return
     */
    public Boolean verifyPaySignTrue(PayAsyncVo payAsyncVo) {
        Map<String, String> params = JSONObject.parseObject(JSONObject.toJSONString(payAsyncVo), Map.class);
        try {
            boolean rsa2 = AlipaySignature.rsaCheckV1(params, publicKey, "utf-8", "RSA2");
            if (rsa2) {
                //签名验证通过
                log.info("异步回调验证通过");
                //开启业务检查处理
                int payLogId = Integer.parseInt(payAsyncVo.getPassback_params());
                Paylog paylog = this.iPaylogService.getById(payLogId);
                //对比订单编号
                if (!payAsyncVo.getOut_trade_no().equals(paylog.getOrdersn())) {
                    return false;
                }
                //请求时 支付的金额 与支付的金额不一致也返回false
                if (!payAsyncVo.getInvoice_amount().equals(paylog.getPayprice().toString())) {
                    return false;
                }
                //变更订单 状态 【分布式锁，悲观锁】 获取订单对象 查看订单状态是否为 未确认 并且支付为支付
                //直接对数据库进行操作 不需要查询 直接变更
                //判断是否支付成功
                if (payStatus.equals(payAsyncVo.getTrade_status())) {

                    String content = paylog.getContent();
                    StringBuffer payLogBuffer = new StringBuffer(content);
                    payLogBuffer.append("订单编号为：" + payAsyncVo.getOut_trade_no() + LocalDateTime.now() + "支付成功");
                    paylog.setContent(payLogBuffer.toString());
                    paylog.setStatus(1);
                    this.iPaylogService.updateById(paylog);

                    if (this.iOrdersService.updateOrderStatus(payAsyncVo.getOut_trade_no()) == 0) {
                        return true;
                    }
                    return false;
                }
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return false;
    }
}
